package com.hmdp.ThreadUtil.pc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *@Author:fengxiaohui
 *@Description:
 Lock版本的生产者消费者
 */
public class Task2 {
    public static void main(String[] args) throws InterruptedException {
        Date1 date = new Date1();
        Thread a = new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    date.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A");

       Thread b = new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    date.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B");
       a.start();
       b.start();



    }
}

//资源类
//JUC口诀：1、线程 操作 资源类
//2、判断、干活、通知
/**
 * @Description:JUC口诀
1、线程 操作 资源类
2、判断、干活、通知
3、防止虚假唤醒，wait方法要注意
4、注意flag标志位，可能是volatile的
 */
class Date1{
    private int number = 0;
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    public  void increment() throws InterruptedException {

        try{

            lock.lock();
            //判断
            //防止虚假唤醒，wait方法要注意
            while (number != 0) {
                condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"=>" + number);
            //通知其他线程，我+1完毕了
            condition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }


    }

    public synchronized void decrement() throws InterruptedException {

        try{
            lock.lock();
            while (number == 0) {
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName()+"=>" + number);
            //通知其他线程，我-1完毕了
            condition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }


    }
}